package servicios;

import interfaces.IServicioCliente;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;

import negocio.Cliente;
import negocio.CondicionDePago;
import negocio.CondicionDePagoCliente;
import negocio.CondicionTributaria;
import negocio.DescuentoCliente;
import negocio.DescuentoClienteMarca;
import negocio.DescuentoClienteNacionalidad;
import negocio.DescuentoClienteProducto;
import negocio.DescuentoClienteSKF;
import negocio.Marca;
import negocio.Nacionalidad;
import negocio.Producto;
import negocio.SKF;

import utiles.Converters;
import utiles.Secciones;
import dao.annotations.DAOCliente;
import dao.annotations.DAOCondicionDePago;
import dao.annotations.DAOCondicionTributaria;
import dao.interfaces.IDAOCliente;
import dao.interfaces.IDAOCondicionDePago;
import dao.interfaces.IDAOCondicionTributaria;
import dao.interfaces.IDAOMarca;
import dao.interfaces.IDAONacionalidad;
import dao.interfaces.IDAOProducto;
import dao.interfaces.IDAOSKF;
import dto.DTOCliente;
import dto.DTOProducto;
import filtros.FiltroCliente;

public class ServicioCliente extends Servicio implements IServicioCliente {
	private static final long serialVersionUID = 1L;
	private IDAOCliente daoCliente;
	private IDAOMarca daoMarca;
	private IDAONacionalidad daoNacionalidad;
	private IDAOProducto daoProducto;
	private IDAOSKF daoSKF;
	private IDAOCondicionDePago daoCondicionDePago;
	private IDAOCondicionTributaria daoCondicionTributaria;

	public ServicioCliente() throws RemoteException {
		super();
		daoCliente = new DAOCliente();
		daoCondicionDePago = new DAOCondicionDePago();
		daoCondicionTributaria = new DAOCondicionTributaria();
	}

	@Override
	public Integer altaCliente(String nombre, String cuit, String direccion,
			String telefono) throws RemoteException {
		try {
			daoCliente.openSession();
			daoCliente.beginTransaction();
			Cliente entidad = new Cliente();
			entidad.setNombre(nombre);
			entidad.setCuit(cuit);
			entidad.setDireccion(direccion);
			entidad.setTelefono(telefono);
			Integer ret = daoCliente.agregar(entidad);
			daoCliente.comitTransaction();
			return ret;
		} catch (Exception e) {
			daoCliente.rollbackTransaction();
			e.printStackTrace();
			throw new RemoteException();
		} finally {
			daoCliente.closeSession();
			notifyObservers(Secciones.Clientes);
		}
	}

	@Override
	public void bajaCliente(Integer codigo) throws RemoteException {
		try {
			daoCliente.openSession();
			daoCliente.beginTransaction();
			Cliente entidad = daoCliente.obtener(codigo);
			daoCliente.eliminar(entidad);
			daoCliente.comitTransaction();
		} catch (Exception e) {
			daoCliente.rollbackTransaction();
			e.printStackTrace();
			throw new RemoteException();
		} finally {
			daoCliente.closeSession();
			notifyObservers(Secciones.Clientes);
		}
	}

	@Override
	public void modificarCliente(Integer codigo, String nombre, String cuit,
			String direccion, String telefono) throws RemoteException {
		try {
			daoCliente.openSession();
			daoCliente.beginTransaction();
			Cliente entidad = daoCliente.obtener(codigo);
			entidad.setNombre(nombre);
			entidad.setCuit(cuit);
			entidad.setDireccion(direccion);
			entidad.setTelefono(telefono);

			daoCliente.grabar(entidad);
			daoCliente.comitTransaction();
		} catch (Exception e) {
			daoCliente.rollbackTransaction();
			e.printStackTrace();
			throw new RemoteException();
		} finally {
			daoCliente.closeSession();
			notifyObservers(Secciones.Clientes);
		}
	}

	@Override
	public DTOCliente obtenerClientePorCuit(String cuit) throws RemoteException {
		try {
			daoCliente.openSession();
			DTOCliente dto = Converters
					.convertToDTO(daoCliente.obtenerClientePorCuit(cuit));
			return dto;
		} catch (Exception e) {
			e.printStackTrace();
			throw new RemoteException();
		} finally {
			daoCliente.closeSession();
		}
	}

	@Override
	public DTOCliente obtenerCliente(Integer codigo) throws RemoteException {
		try {
			daoCliente.openSession();
			DTOCliente dto = Converters
					.convertToDTO(daoCliente.obtener(codigo));
			return dto;
		} catch (Exception e) {
			e.printStackTrace();
			throw new RemoteException();
		} finally {
			daoCliente.closeSession();
		}
	}

	@Override
	public List<DTOCliente> listarClientes(Integer codigo, String nombre)
			throws RemoteException {
		try {
			daoCliente.openSession();

			FiltroCliente filtro = new FiltroCliente();
			filtro.codigo = codigo;
			filtro.nombre = nombre;

			List<Cliente> Clientes = daoCliente.listar(filtro);
			List<DTOCliente> dtoClientes = new ArrayList<DTOCliente>();
			for (Cliente Cliente : Clientes) {
				dtoClientes.add(Converters.convertToDTO(Cliente));
			}
			return dtoClientes;
		} catch (Exception e) {
			e.printStackTrace();
			throw new RemoteException();
		} finally {
			daoCliente.closeSession();
		}
	}

	@Override
	public void altaCondicionDePagoCliente(Integer codigoCliente,
			Integer codigoCondicionDePago, Float interes)
			throws RemoteException {
		try {
			daoCliente.openSession();
			daoCliente.beginTransaction();
			Cliente entidad = daoCliente.obtener(codigoCliente);
			CondicionDePago condicion = daoCondicionDePago
					.obtener(codigoCondicionDePago);
			entidad.agregarCondicionDePago(condicion, interes);
			daoCliente.grabar(entidad);
			daoCliente.comitTransaction();
		} catch (Exception e) {
			daoCliente.rollbackTransaction();
			e.printStackTrace();
			throw new RemoteException();
		} finally {
			daoCliente.closeSession();
		}
	}

	@Override
	public void modificarCondicionDePagoCliente(Integer codigoCliente,
			Integer codigo, Integer codigoCondicionDePago, Float interes)
			throws RemoteException {
		try {
			daoCliente.openSession();
			daoCliente.beginTransaction();
			Cliente entidad = daoCliente.obtener(codigoCliente);
			CondicionDePago condicion = daoCondicionDePago
					.obtener(codigoCondicionDePago);
			CondicionDePagoCliente item = entidad
					.obtenerCondicionDePago(codigo);
			item.setCondicionDePago(condicion);
			item.setInteres(interes);
			daoCliente.grabar(entidad);
			daoCliente.comitTransaction();
		} catch (Exception e) {
			daoCliente.rollbackTransaction();
			e.printStackTrace();
			throw new RemoteException();
		} finally {
			daoCliente.closeSession();
		}
	}

	@Override
	public void bajaCondicionDePagoCliente(Integer codigoCliente, Integer codigo)
			throws RemoteException {
		try {
			daoCliente.openSession();
			daoCliente.beginTransaction();
			Cliente entidad = daoCliente.obtener(codigoCliente);
			entidad.eliminarCondicionDePago(codigo);
			daoCliente.grabar(entidad);
			daoCliente.comitTransaction();
		} catch (Exception e) {
			daoCliente.rollbackTransaction();
			e.printStackTrace();
			throw new RemoteException();
		} finally {
			daoCliente.closeSession();
		}
	}

	@Override
	public void altaDescuentoClienteMarca(Integer codigoCliente, String nombre,
			Float descuento, Integer codigoMarca) throws RemoteException {
		try {
			daoCliente.openSession();
			daoCliente.beginTransaction();
			Cliente entidad = daoCliente.obtener(codigoCliente);
			Marca marca = daoMarca.obtener(codigoMarca);
			entidad.agregarDescuento(nombre, descuento, marca);
			daoCliente.grabar(entidad);
			daoCliente.comitTransaction();
		} catch (Exception e) {
			daoCliente.rollbackTransaction();
			e.printStackTrace();
			throw new RemoteException();
		} finally {
			daoCliente.closeSession();
		}
	}

	@Override
	public void altaDescuentoClienteNacionalidad(Integer codigoCliente,
			String nombre, Float descuento, Integer codigoNacionalidad)
			throws RemoteException {
		try {
			daoCliente.openSession();
			daoCliente.beginTransaction();
			Cliente entidad = daoCliente.obtener(codigoCliente);
			Nacionalidad nacionalidad = daoNacionalidad
					.obtener(codigoNacionalidad);
			entidad.agregarDescuento(nombre, descuento, nacionalidad);
			daoCliente.grabar(entidad);
			daoCliente.comitTransaction();
		} catch (Exception e) {
			daoCliente.rollbackTransaction();
			e.printStackTrace();
			throw new RemoteException();
		} finally {
			daoCliente.closeSession();
		}
	}

	@Override
	public void altaDescuentoClienteProducto(Integer codigoCliente,
			String nombre, Float descuento, Integer codigo)
			throws RemoteException {
		try {
			daoCliente.openSession();
			daoCliente.beginTransaction();
			Cliente entidad = daoCliente.obtener(codigoCliente);
			Producto producto = daoProducto.obtener(codigo);
			entidad.agregarDescuento(nombre, descuento, producto);
			daoCliente.grabar(entidad);
			daoCliente.comitTransaction();
		} catch (Exception e) {
			daoCliente.rollbackTransaction();
			e.printStackTrace();
			throw new RemoteException();
		} finally {
			daoCliente.closeSession();
		}
	}

	@Override
	public void altaDescuentoClienteSKF(Integer codigoCliente, String nombre,
			Float descuento, String codigo) throws RemoteException {
		try {
			daoCliente.openSession();
			daoCliente.beginTransaction();
			Cliente entidad = daoCliente.obtener(codigoCliente);
			SKF skf = daoSKF.obtener(codigo);
			entidad.agregarDescuento(nombre, descuento, skf);
			daoCliente.grabar(entidad);
			daoCliente.comitTransaction();
		} catch (Exception e) {
			daoCliente.rollbackTransaction();
			e.printStackTrace();
			throw new RemoteException();
		} finally {
			daoCliente.closeSession();
		}
	}

	@Override
	public void bajaDescuentoCliente(Integer codigoCliente, Integer codigo)
			throws RemoteException {
		try {
			daoCliente.openSession();
			daoCliente.beginTransaction();
			Cliente entidad = daoCliente.obtener(codigoCliente);
			entidad.eliminarDescuento(codigo);
			daoCliente.grabar(entidad);
			daoCliente.comitTransaction();
		} catch (Exception e) {
			daoCliente.rollbackTransaction();
			e.printStackTrace();
			throw new RemoteException();
		} finally {
			daoCliente.closeSession();
		}
	}

	@Override
	public void modificarDescuentoClienteMarca(Integer codigoCliente,
			Integer codigoDesc, String nombre, Float descuento, Integer codigo)
			throws RemoteException {
		try {
			daoCliente.openSession();
			daoCliente.beginTransaction();
			Cliente entidad = daoCliente.obtener(codigoCliente);
			DescuentoCliente item = entidad.obtenerDescuento(codigoDesc);
			if (DescuentoClienteMarca.class.isInstance(item)) {
				Marca marca = daoMarca.obtener(codigo);
				DescuentoClienteMarca obj = (DescuentoClienteMarca) item;
				obj.setMarca(marca);
			}
			item.setNombre(nombre);
			item.setDescuento(descuento);
			daoCliente.grabar(entidad);
			daoCliente.comitTransaction();
		} catch (Exception e) {
			daoCliente.rollbackTransaction();
			e.printStackTrace();
			throw new RemoteException();
		} finally {
			daoCliente.closeSession();
		}
	}
	
	@Override
	public void modificarDescuentoClienteNacionalidad(Integer codigoCliente,
			Integer codigoDesc, String nombre, Float descuento, Integer codigo)
			throws RemoteException {
		try {
			daoCliente.openSession();
			daoCliente.beginTransaction();
			Cliente entidad = daoCliente.obtener(codigoCliente);
			DescuentoCliente item = entidad.obtenerDescuento(codigoDesc);
			if (DescuentoClienteNacionalidad.class.isInstance(item)) {
				Nacionalidad nacionalidad = daoNacionalidad.obtener(codigo);
				DescuentoClienteNacionalidad obj = (DescuentoClienteNacionalidad) item;
				obj.setNacionalidad(nacionalidad);
			}
			item.setNombre(nombre);
			item.setDescuento(descuento);
			daoCliente.grabar(entidad);
			daoCliente.comitTransaction();
		} catch (Exception e) {
			daoCliente.rollbackTransaction();
			e.printStackTrace();
			throw new RemoteException();
		} finally {
			daoCliente.closeSession();
		}
	}

	@Override
	public void modificarDescuentoClienteProducto(Integer codigoCliente,
			Integer codigoDesc, String nombre, Float descuento, Integer codigo)
			throws RemoteException {
		try {
			daoCliente.openSession();
			daoCliente.beginTransaction();
			Cliente entidad = daoCliente.obtener(codigoCliente);
			DescuentoCliente item = entidad.obtenerDescuento(codigoDesc);
			if (DescuentoClienteProducto.class.isInstance(item)) {
				Producto producto = daoProducto.obtener(codigo);
				DescuentoClienteProducto obj = (DescuentoClienteProducto) item;
				obj.setProducto(producto);
			}
			item.setNombre(nombre);
			item.setDescuento(descuento);
			daoCliente.grabar(entidad);
			daoCliente.comitTransaction();
		} catch (Exception e) {
			daoCliente.rollbackTransaction();
			e.printStackTrace();
			throw new RemoteException();
		} finally {
			daoCliente.closeSession();
		}
	}

	@Override
	public void modificarDescuentoClienteSKF(Integer codigoCliente,
			Integer codigoDesc, String nombre, Float descuento, String codigo)
			throws RemoteException {
		try {
			daoCliente.openSession();
			daoCliente.beginTransaction();
			Cliente entidad = daoCliente.obtener(codigoCliente);
			DescuentoCliente item = entidad.obtenerDescuento(codigoDesc);
			if (DescuentoClienteSKF.class.isInstance(item)) {
				SKF skf = daoSKF.obtener(codigo);
				DescuentoClienteSKF obj = (DescuentoClienteSKF) item;
				obj.setSkf(skf);
			}
			item.setNombre(nombre);
			item.setDescuento(descuento);
			daoCliente.grabar(entidad);
			daoCliente.comitTransaction();
		} catch (Exception e) {
			daoCliente.rollbackTransaction();
			e.printStackTrace();
			throw new RemoteException();
		} finally {
			daoCliente.closeSession();
		}
	}

	@Override
	public void altaCondicionTributaria(Integer codigoCliente, Integer codigo)
			throws RemoteException {
		try {
			daoCliente.openSession();
			daoCliente.beginTransaction();
			Cliente entidad = daoCliente.obtener(codigoCliente);
			CondicionTributaria condicion = daoCondicionTributaria
					.obtener(codigo);
			entidad.setCondicionTributaria(condicion);
			daoCliente.grabar(entidad);
			daoCliente.comitTransaction();
		} catch (Exception e) {
			daoCliente.rollbackTransaction();
			e.printStackTrace();
			throw new RemoteException();
		} finally {
			daoCliente.closeSession();
		}
	}

	@Override
	public void modificarCondicionTributaria(Integer codigoCliente,
			Integer codigo, Integer codigoCondicionTributaria)
			throws RemoteException {
		try {
			daoCliente.openSession();
			daoCliente.beginTransaction();
			Cliente entidad = daoCliente.obtener(codigoCliente);
			CondicionTributaria condicion = daoCondicionTributaria
					.obtener(codigoCondicionTributaria);
			entidad.setCondicionTributaria(condicion);
			daoCliente.grabar(entidad);
			daoCliente.comitTransaction();
		} catch (Exception e) {
			daoCliente.rollbackTransaction();
			e.printStackTrace();
			throw new RemoteException();
		} finally {
			daoCliente.closeSession();
		}
	}

	@Override
	public void bajaCondicionTributaria(Integer codigoCliente, Integer codigo)
			throws RemoteException {
		try {
			daoCliente.openSession();
			daoCliente.beginTransaction();
			Cliente entidad = daoCliente.obtener(codigoCliente);
			entidad.eliminarCondicionDePago(codigo);
			daoCliente.grabar(entidad);
			daoCliente.comitTransaction();
		} catch (Exception e) {
			daoCliente.rollbackTransaction();
			e.printStackTrace();
			throw new RemoteException();
		} finally {
			daoCliente.closeSession();
		}
	}

	@Override
	public DTOProducto obtenerProducto(Integer codigo) throws RemoteException {
		return null;
	}

}
